// ==UserScript==
// @name LouProof
// @description User Interface enhancements for Lord of Ultima online
// @include http://prodgame*.lordofultima.com/6/index.aspx?sessionId=*
// @namespace http://userscripts.org/users/scheper
// ==/UserScript==

injection = function() {

    LouProof = function () {
    }
    
    // Dump, similar to php's print_r
    
    LouProof.prototype.dump = function(arr, max_level, level) {
    
        if( !max_level) max_level = 1;
        var dumped_text = "";
        if (!level) level = 0;
    
        //The padding given at the beginning of the line.
        var level_padding = "";
        for (var j = 0; j < level + 1; j++) level_padding += "    ";
    
        if (typeof(arr) == 'object') { //Array/Hashes/Objects
            for (var item in arr) {
                var value = arr[item];
    
                if (typeof(value) == 'object') { //If it is an array,
                    dumped_text += level_padding + "'" + item + "' ...\n";
                    
                    if( level < max_level) dumped_text += dump(value, 0, level + 1);
                } else {
                    dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
                }
            }
        } else { //Stings/Chars/Numbers etc.
            dumped_text = "===>" + arr + "<===(" + typeof(arr) + ")";
        }
        return dumped_text;
    }
    
    LouProof.prototype.options_page = function() {
    	page = new webfrontend.gui.ConfirmationWidget();
    	
    	var bgImg = new qx.ui.basic.Image("webfrontend/ui/bgr_detailinfo_br.png");
    	page.dialogBackground._add(bgImg, {left: 0, top: 0});
    	
    	var la = new qx.ui.basic.Label("Shortcut Options");
    		la.setFont("font_subheadline_sidewindow");
    		la.setTextColor("text-gold");
    		la.setTextAlign("left");
    	page.dialogBackground._add(la, {left: 17, top: 5});
    		
    	var okButton = new qx.ui.form.Button("OK");
    		okButton.setWidth(120);
    		okButton.addListener("click", function(){page.disable();}, false);
    	page.dialogBackground._add(okButton, {left: 440, top: 210});
    	
    	a.getDesktop().add(page, {left: 0, right: 0, top: 0, bottom: 0});
    }
    
    LouProof.prototype.upgrade_vis = function() {
        var cityid = a.buildingDetailView.cityId;
        var placeid = a.buildingDetailView.visBuilding.getId();
        var typeid = a.buildingDetailView.visBuilding.getType();
        
        this.upgrade( cityid, placeid, typeid, true);
    }
    
    LouProof.prototype.upgrade_bld = function( bld, isPaid) {
    	var cityid = wfe.data.City.getInstance().getId();
    	
    	if( bld) {
    		var placeid = bld.getId();
    		var typeid = bld.getType();
    	
    		this.upgrade( cityid, placeid, typeid, isPaid);
    	} else {
            if( debuck) console.log( 'Can\'t upgrade non-specified building: '+bld);
    	}
    }
    
    LouProof.prototype.upgrade = function( cityid, placeid, typeid, isPaid) {
    	
    	// Making sure there's enough room in the build queue
    	
    	var maxq = webfrontend.data.Player.getInstance().getMaxBuildQueueSize();
    	var qsize = this.building_queue_size();
    	
    	if( qsize >= maxq) {
            if( debuck) console.log( 'Can\'t upgrade building, queue is full!');
    		return;
    	}
    	
        if( debuck) console.log( 'upgrading');
    	if( debuck) console.log( 'Upgrading building (cityid, buildingid, type) '+
    							 '('+cityid+', '+placeid+', '+typeid+')');
    	
        webfrontend.net.CommandManager.getInstance().sendCommand(
            'UpgradeBuilding', {
            cityid: cityid,
            buildingid: placeid,
            buildingType: typeid,
            isPaid: isPaid
        }, this, this._onBuildDone, this.cntSetPlace);
        // upgrade( a.buildingDetailView.cityId, a.buildingDetailView.visBuilding.getId(), a.buildingDetailView.visBuilding.getType());
    }
    
    LouProof.prototype.buy_moonstone = function() {
    	
    	var moontowerid = this.get_moonstone_tower();
    	
    	if( !moontowerid) {
            if( debuck) console.log( "No level 10 moonglow tower found");
    		return;
    	}
    	
        webfrontend.net.CommandManager.getInstance().sendCommand('CreateMoonStone', {
            cityid: wfe.data.City.getInstance().getId(),
            buildingid: moontowerid
        }, null, null);
    }
    
    LouProof.prototype.get_moonstone_tower = function() {
    	var buildings = a.visMain.getBuildings();
    	
    	for (var i=0; i<buildings.length; i++) {
    		if( (buildings[i].getType() == 36) && (buildings[i].getLevel() == 10) )
    			return buildings[i].getId();
    	}
    	
    	return false;
    }
    
    LouProof.prototype.building_queue_size = function() {
    	// returns the number of buildings in the build queue
    
    	city = webfrontend.data.City.getInstance();
    	
    	if( city.hasBuildQueue()) {
    		return city.getBuildQueue().length;
    	} else {
    		return 0;
    	}
    }
    
    LouProof.prototype.downgrade = function() {
        var cityid = a.buildingDetailView.cityId;
        var placeid = a.buildingDetailView.visBuilding.getId();
        var typeid = a.buildingDetailView.visBuilding.getType();
        
        webfrontend.net.CommandManager.getInstance().sendCommand(
            'DowngradeBuilding', {
            cityid: cityid,
            buildingid: placeid,
            buildingType: typeid,
            isPaid: true
        }, this, this._onBuildDone, this.cntSetPlace);
        // downgrade( a.buildingDetailView.cityId, a.buildingDetailView.visBuilding.getId(), a.buildingDetailView.visBuilding.getType());
    }
    
    LouProof.prototype.chatSelectable = function() {
        // Makes the chat area selectable
        // Would be great if lines were selectable when they were added
        // instead of looping through it
    
        if(a.chat === null || a.chat.chatViewComposite === null) return;
        
        for( var cvc=0; cvc<a.chat.chatViewComposite.length; cvc++) {
    
            if( a.chat.chatViewComposite[ cvc].__ei === null) continue;
    
            for( var line=0; line<a.chat.chatViewComposite[ cvc].__ei.length; line++) {
    
                a.chat.chatViewComposite[cvc].__ei[ line].setSelectable( true);
            }
        }
    }
    
    LouProof.prototype.from_hash = function( hashId) {
    	return qx.core.ObjectRegistry.fromHashCode( hashId);
    }
    
    LouProof.prototype.qcount = function( bld) {
    	// Returns the number of times a building is in the building queue
    	
    	city = wfe.data.City.getInstance();
    	count = 0;
    	
    	if(! city["buildQueue"]) return 0; // If there's no queue, return 0
    	
    	for( var i=0; i<city.buildQueue.length; i++) {
    		if( city.buildQueue[i].building == bld.getId()) {
    			count++;
    			if( debuck) console.log( 'Building found in queue: '+ bld.getId());
    		}
    	}
    	
    	return count;
    }
    
    // Simple play sound routine using the new HTML5 audio element
    
    LouProof.prototype.play_sound = function( src) {
    	var sound = new Audio( src);
    	sound.play();
    }
    
    // Initialisation routine
    
    LouProof.prototype.init = function() {
    
        wfe = webfrontend;
    
    	p = wfe.data.Player.getInstance();
    	c = wfe.data.Chat.getInstance();
    	a = qx.core.Init.getApplication();
    
        // Chat selectable routine
        //setInterval( "louproof.chatSelectable();", 2000);
    
        // replacing standard error handling
        qx.event.GlobalError.setErrorHandler(function(ex) {
            if( debuck) console.log(ex);
          });
    
        debuck = false;
    	
        this.populate_build_times();
    
        // Default options
        
        if( !localStorage["moonstone"]) localStorage["moonstone"] = "false";
        if( !localStorage["beep_on_name"]) localStorage["beep_on_name"] = "true";
        if( !localStorage["lowest_build_time"]) localStorage["lowest_build_time"] = "false";
        if( !localStorage["show_max_storage"]) localStorage["show_max_storage"] = "true";
    
        // Chat parsing
        webfrontend.data.Chat.getInstance().addListener( 'newMessage', function(e)
        	{
        		var re = new RegExp( p.$$user_name, 'i');
        		
        		if ( (re.test( e.getData().m)) && (localStorage["beep_on_name"] == "true")) {
                    //TODO: Access alert.ogg from within the plugin
        			//this.play_sound( "chrome-extension://pmjkjnnfljmjjcpaenohknbhnpidlhml/alert.ogg");
        			louproof.play_sound( "http://canvas.xieke.com/paddlewar_paddlebounce.ogg");
                }
    
                setTimeout( "louproof.chatSelectable();", 500);
        	});
    	
        // Keyboard shortcuts
    	a.mainContainer.addListener( 'keypress', function(key) {
    	    
    	    if( !a.allowHotKey) { return; } // this is false if the chat input box is active
    	    
    	    var visbuilding = a.buildingDetailView.visBuilding; // can't do upgrade/downgrade without
    	    												// building being selected
    	    
    	    var identifier = key.getKeyIdentifier();
    	    var shift = key.isShiftPressed();
    	    var ctrl = key.isCtrlPressed();
    
    	    if( debuck) console.log( 'Key pressed.identifier = '+ identifier);
    	    
    	    if( identifier == 'U' && visbuilding) { // upgrade
    	        if( shift) { // full upgrade
    	            var level = a.buildingDetailView.visBuilding.getLevel();
    	            
    	            for( var i=level; i<10; i++) {
    	                louproof.upgrade_vis();
    	            }
    	        } else { // single upgrade
    	            louproof.upgrade_vis();
    	        }
    	    }
    	    
    	    if( identifier == 'D' && visbuilding) { // downgrade
    	        if( shift) { // full downgrade
    	            level = a.buildingDetailView.visBuilding.getLevel();
    	            
    	            for( var i=level; i>0; i--) {
    	                louproof.downgrade();
    	            }
    	        } else { // single downgrade
    	            louproof.downgrade();
    	        }
    	    }
    	    
    	    if( identifier == '[') { // previous city
    	    	a.cityBar.prevButton.execute();
    	    }
    	    
    	    if( identifier == ']') { // next city
    	    	a.cityBar.nextButton.execute();
    	    }
    	    
    	    // Lowest level building upgrades
    	    
    	    if( identifier == 'M') { // upgrade lowest level military building
    	    	louproof.upgrade_bld( louproof.get_lowest_level_building( 'military'), !shift);
    	    }
    	    
    	    if( identifier == 'C') { // upgrade lowest level cottage
    	    	louproof.upgrade_bld( louproof.get_lowest_level_building( 'cottage'), !shift);
    	    }
    
    	    if( identifier == 'B') { // upgrade lowest level barracks
    	    	louproof.upgrade_bld( louproof.get_lowest_level_building( 'barracks'), !shift);
    	    }
    	    
    	    if( identifier == 'T') { // upgrade lowest level tower
    	    	louproof.upgrade_bld( louproof.get_lowest_level_building( 'tower'), !shift);
    	    }
    	    
    	    if( identifier == 'A') { // Upgrade lowest level building
        		louproof.upgrade_bld( louproof.get_lowest_level_building( 'all'), !shift);
    	    }
    	    
    	    if( identifier == 'L') { // upgrade lowest level common building
        		louproof.upgrade_bld( louproof.get_lowest_level_building( 'common'), !shift);
    	    }
    	    
    	    if( identifier == 'R') { // show recruitment window
    	    	qx.core.Init.getApplication().showRecruting();
    	    }
    	    
    	    //if( identifier == 'T') { // show trade (but not go outside city)
    //	    	qx.core.Init.getApplication().showTrade();
    	    //}
    	    
    	    if( identifier == '+') { // Maximize chat window width
    	    	for(var i=1; i<=3; i++) {
    	    		a.chat.chatSize[ i].width = screen.width-500;
    	    	}
    	    	
    	    	if( debuck) console.log( 'Maximizing chat window width');
    	    	a.chat.setSizeMode( a.chat.sizeMode);
    	    }
    	    
    	    if( identifier == 'S') {
    	    	// Buy moonstones
    	    	
    	    	if( (localStorage["moonstone"] == "false") && 
    	    		((a.buildingDetailView.visBuilding == null) ||
    	    		(!a.buildingDetailView['buyMoonstoneButton'].getEnabled()))) {
    	    		//alert( "no can do!");
    	    		return;
    	    	}
    	    	
    	    	if( shift) { // Buy 10 of em!
    	    		for( var i=0; i<10; i++) {
    	    			louproof.buy_moonstone();
    	    		}
    	    	} else { // Buy just one of em
    	    		louproof.buy_moonstone();
    	    	}
    	    }
    	    
    	    if( identifier == 'O') {
    	    	// Show options page
    	    	louproof.show_options_window();
    	    }
    	    
    	    if( identifier == '-') { // Restore chat window width
    	    	for(var i=1; i<=3; i++) {
    	    		a.chat.chatSize[ i].width = 600;
    	    	}
    	    	
    	    	if( debuck) console.log( 'Restoring chat window width');
    	    	a.chat.setSizeMode( a.chat.sizeMode);
    	    }
    	    
    	    if( identifier == ';') {
    	    	var re = /^([0-9]+)[:,-]([0-9]+)$/;
    	    	var coords = prompt( "Enter co-ordinates");
    	    	
    	    	if( re.test( coords)) {
    	    		var co_ar = re.exec( coords);
    	    		
    	    		var output = '[u][w='+ co_ar[1]*128 +';'+ co_ar[2]*80 +
    	    					 ']'+ coords +'[/w][/u]';
    
    	    		var curvalue = '';
    	    		
    	    		if( !(a.chat.chatLine.getValue() == null))
    	    			curvalue = a.chat.chatLine.getValue();
    		
    	    		if ( curvalue == 'nl') curvalue = '';
    	    		a.chat.chatLine.setValue( curvalue + output);
    	    		setTimeout( "a.chat.chatLine.focus()", 100); // Delay otherwise it adds the C to the end of the line
    	    	}
    	    }
    	    	
    	}, null);
    	
    	if( p.$$user_name == "chainsawdaz")
        {
            //wfe.data.Chat.getInstance().addMsg( msg[louproof.rnd(8)]);
        }
        
    
        // Setting resource label values
    
        if( localStorage["show_max_storage"] == "true") {
            try {
                var rv = a.cityBar.resValueLabels;
    
                var rv_s = rv[1]._applyValue.toString();
                //var matches = rv_s.match( /^function \((\w+),(\w+)\){([^]*)}/m);
                var matches = rv_s.match( /^function \((\w+),\s*(\w+)\)\s*{([^]*)}/m)
    
                var arg1 = matches[1];
                var arg2 = matches[2]
                var body = matches[3];
    
                matches = rv_s.match( /this\.fireDataEvent\((\w+),/);
    
                var arg3 = matches[1];
    
                for( var i=1; i<=4; i++) {
                    var new_body = "\
                    \
                    var max = webfrontend.data.City.getInstance().getResourceMaxStorage("+i+");\
                    var new_value;\
                    var "+arg3+"='changeContent';\
                    \
                    if( "+arg1+" > 999999) {\
                        "+arg1+" = Math.floor( "+arg1+"/100000)/10 +'`'+ Math.floor( max/100000)/10 +'m';\
                    } else {\
                    "+arg1+" = Math.floor( "+arg1+"/1000) +'`'+ Math.floor( max/1000) +'k';\
                    }";
    
                    new_body += body;
    
                    rv[i]._applyValue = new Function( arg1, arg2, new_body);
    
                    rv[i]._applyValue( rv[i].getValue(), 0);
            } } catch(e) { console.log( e); }
        }
    }
    
    LouProof.prototype.rnd = function( max) {
        return( Math.floor( Math.random()*max));
    }
    
    LouProof.prototype.is_common_btype = function( btype) {
    	switch( btype) {
    		case 1:
    		case 2:
    		case 3:
    		case 4:
    		case 6:
    		case 7:
    		case 8:
    		case 10:
    		case 11:
    		case 13:
    			return true;
    			break;
    	} 
    
    	return false;
    }
    
    LouProof.prototype.is_resource = function( btype) {
        switch( btype) {
            case 27:
            case 28:
            case 29:
            case 30:
                return true;
                break;
        }
    
        return false;
    }
    	
    LouProof.prototype.is_tower = function( btype) {
    	switch( btype) {
    		case 24:
    		case 25:
    		case 26:
    		case 38:
    		case 39:
    		case 40:
    		case 41:
    		case 42:
    		case 43:
    		case 44:
    		case 45:
    		case 46:
    			return true;
    			break;
    	}
    	
    	return false;
    }
    
    LouProof.prototype.is_barracks = function( btype) {
    	return( btype == 14);
    }
    
    LouProof.prototype.is_cottage = function( btype) {
    	return( btype == 4);
    }
    
    
    LouProof.prototype.is_military = function( btype) {
    	switch( btype) {
    		case 15:
    		case 16:
    		case 17:
    		case 18:
    		case 19:
    		case 36:
    		case 37:
    			return true;
    			break;
    	}
    	
    	return false;
    }
    
    LouProof.prototype.getBldTypeName = function( bldType) {
    	resmain = webfrontend.res.Main.getInstance();
    	
    	return resmain.buildings[bldType].dn;
    }
    
    // LouProof.prototypeoptions_window = webfrontend.gui.overlayWidget;
    
    // * OPTIONS WINDOW
    
    LouProof.prototype.options_window = function() { };
    //LouProof.prototype.options_window.prototype.options = function() { };
    
    LouProof.prototype.show_options_window = function() {
    
        var i =0;
    	this.options_window = new webfrontend.gui.OverlayWidget();
    	var options_canvas = new qx.ui.layout.Canvas();
    
        this.options_window.options = function() {
            this.moonstone = null;
            this.beep_on_name = null;
            this.saveclose = null;
            this.show_max_storage = null;
        }
    	
    	this.options_window.setTitle( this.options_window.tr( 'Keyboard Shortcut Options'));
    	this.options_window.clientArea.setLayout( options_canvas);
    	
    	// Moonstone option
    	
    	this.options_window.options.moonstone = new qx.ui.form.CheckBox( "Buy moonstones without selecting tower");
    	this.options_window.options.moonstone.setFont("font_subheadline_sidewindow");
    	this.options_window.options.moonstone.setTextColor("text-black");
    	
    	if( localStorage["moonstone"] == "true")
    		this.options_window.options.moonstone.setValue( true);
    	
    	// Beep on name option
    	
    	this.options_window.options.beep_on_name = new qx.ui.form.CheckBox( "Beep when user name appears in chat");
    	this.options_window.options.beep_on_name.setFont("font_subheadline_sidewindow");
    	this.options_window.options.beep_on_name.setTextColor("text-black");
    	
    	if( localStorage["beep_on_name"] == "true")
    		this.options_window.options.beep_on_name.setValue( true);
    	
        // Upgrade sort by build time option
        
    	this.options_window.options.lowest_build_time = new qx.ui.form.CheckBox( "Upgrade by lowest build time instead of lowest level");
    	this.options_window.options.lowest_build_time.setFont("font_subheadline_sidewindow");
    	this.options_window.options.lowest_build_time.setTextColor("text-black");
    	
    	if( localStorage["lowest_build_time"] == "true")
    		this.options_window.options.lowest_build_time.setValue( true);
    
        // Show max storage on city resource bar
    
        this.options_window.options.show_max_storage = new qx.ui.form.CheckBox( "Show maximum storage on city resource bar (needs refresh)");
    	this.options_window.options.show_max_storage.setFont("font_subheadline_sidewindow");
    	this.options_window.options.show_max_storage.setTextColor("text-black");
    	
    	if( localStorage["show_max_storage"] == "true")
    		this.options_window.options.show_max_storage.setValue( true);
    
    	// Save & Close button
    	
    	this.options_window.saveclose = new qx.ui.form.Button( "Save & Close");
    	
    	this.options_window.saveclose.addListener( 'execute', function() {
    
                    // TODO: louproof. needs to be replaced with this. or similar
    				localStorage["moonstone"] = louproof.options_window.options.moonstone.getValue();
    				localStorage["beep_on_name"] = louproof.options_window.options.beep_on_name.getValue();
    				localStorage["lowest_build_time"] = louproof.options_window.options.lowest_build_time.getValue();
    				localStorage["show_max_storage"] = louproof.options_window.options.show_max_storage.getValue();
    				louproof.options_window.hide();
    			}
            );
    	
    	// Adding the elements to the client area
    			
    	this.options_window.clientArea.add( this.options_window.options.moonstone,
    			{left: 17, top: 20});
    	this.options_window.clientArea.add( this.options_window.options.beep_on_name,
    			{left: 17, top: 50});
    	this.options_window.clientArea.add( this.options_window.options.lowest_build_time,
    			{left: 17, top: 80});
    	this.options_window.clientArea.add( this.options_window.options.show_max_storage,
    			{left: 17, top: 110});
    	this.options_window.clientArea.add( this.options_window.saveclose,
    			{left: 17, bottom: 10});
    	
    	a.switchOverlay( this.options_window);
    }
    
    // ---------------------
    
    LouProof.prototype.build_time = null;
    
    LouProof.prototype.populate_build_times = function() {
    
        this.build_time = new Array();
    
        this.build_time[12] = new Array(); //Town Hall
        this.build_time[12][1] = 0;
        this.build_time[12][2] = 25;
        this.build_time[12][3] = 40;
        this.build_time[12][4] = 100;
        this.build_time[12][5] = 1800;
        this.build_time[12][6] = 9000;
        this.build_time[12][7] = 18240;
        this.build_time[12][8] = 60000;
        this.build_time[12][9] = 93600;
        this.build_time[12][10] = 134400;
    
        this.build_time[1] = new Array(); //Woodcutter's Hut
        this.build_time[1][1] = 15;
        this.build_time[1][2] = 54;
        this.build_time[1][3] = 360;
        this.build_time[1][4] = 2700;
        this.build_time[1][5] = 6075;
        this.build_time[1][6] = 12150;
        this.build_time[1][7] = 22500;
        this.build_time[1][8] = 35820;
        this.build_time[1][9] = 53880;
        this.build_time[1][10] = 81720;
    
        this.build_time[4] = new Array(); //Cottage
        this.build_time[4][1] = 15;
        this.build_time[4][2] = 54;
        this.build_time[4][3] = 360;
        this.build_time[4][4] = 2700;
        this.build_time[4][5] = 6075;
        this.build_time[4][6] = 12150;
        this.build_time[4][7] = 22500;
        this.build_time[4][8] = 35820;
        this.build_time[4][9] = 53880;
        this.build_time[4][10] = 81720;
    
        this.build_time[20] = new Array(); //Warehouse
        this.build_time[20][1] = 15;
        this.build_time[20][2] = 36;
        this.build_time[20][3] = 240;
        this.build_time[20][4] = 1800;
        this.build_time[20][5] = 4050;
        this.build_time[20][6] = 4500;
        this.build_time[20][7] = 14760;
        this.build_time[20][8] = 23850;
        this.build_time[20][9] = 35910;
        this.build_time[20][10] = 54450;
    
        this.build_time[23] = new Array(); //City Wall
        this.build_time[23][1] = 30;
        this.build_time[23][2] = 1200;
        this.build_time[23][3] = 3600;
        this.build_time[23][4] = 10800;
        this.build_time[23][5] = 18000;
        this.build_time[23][6] = 28800;
        this.build_time[23][7] = 43200;
        this.build_time[23][8] = 64800;
        this.build_time[23][9] = 90000;
        this.build_time[23][10] = 126000;
    
        this.build_time[2] = new Array(); //Quarry
        this.build_time[2][1] = 15;
        this.build_time[2][2] = 54;
        this.build_time[2][3] = 360;
        this.build_time[2][4] = 2700;
        this.build_time[2][5] = 6075;
        this.build_time[2][6] = 12150;
        this.build_time[2][7] = 22500;
        this.build_time[2][8] = 35820;
        this.build_time[2][9] = 53880;
        this.build_time[2][10] = 81720;
    
        this.build_time[9] = new Array(); //Hideout
        this.build_time[9][1] = 15;
        this.build_time[9][2] = 36;
        this.build_time[9][3] = 240;
        this.build_time[9][4] = 1800;
        this.build_time[9][5] = 4050;
        this.build_time[9][6] = 8100;
        this.build_time[9][7] = 14760;
        this.build_time[9][8] = 23850;
        this.build_time[9][9] = 35910;
        this.build_time[9][10] = 54450;
    
        this.build_time[38] = new Array(); //Lookout Tower
        this.build_time[38][1] = 25;
        this.build_time[38][2] = 300;
        this.build_time[38][3] = 810;
        this.build_time[38][4] = 1500;
        this.build_time[38][5] = 2400;
        this.build_time[38][6] = 3600;
        this.build_time[38][7] = 4920;
        this.build_time[38][8] = 6600;
        this.build_time[38][9] = 8700;
        this.build_time[38][10] = 12000;
    
        this.build_time[3] = new Array(); //Farm
        this.build_time[3][1] = 15;
        this.build_time[3][2] = 54;
        this.build_time[3][3] = 360;
        this.build_time[3][4] = 2700;
        this.build_time[3][5] = 6075;
        this.build_time[3][6] = 12150;
        this.build_time[3][7] = 22500;
        this.build_time[3][8] = 35820;
        this.build_time[3][9] = 53880;
        this.build_time[3][10] = 81720;
    
        this.build_time[15] = new Array(); //City Guard House
        this.build_time[15][1] = 17;
        this.build_time[15][2] = 72;
        this.build_time[15][3] = 480;
        this.build_time[15][4] = 3600;
        this.build_time[15][5] = 8100;
        this.build_time[15][6] = 16200;
        this.build_time[15][7] = 29520;
        this.build_time[15][8] = 47700;
        this.build_time[15][9] = 71820;
        this.build_time[15][10] = 109200;
    
        this.build_time[41] = new Array(); //Ranger Tower
        this.build_time[41][1] = 25;
        this.build_time[41][2] = 300;
        this.build_time[41][3] = 810;
        this.build_time[41][4] = 1500;
        this.build_time[41][5] = 2400;
        this.build_time[41][6] = 3600;
        this.build_time[41][7] = 4920;
        this.build_time[41][8] = 6600;
        this.build_time[41][9] = 8700;
        this.build_time[41][10] = 12000;
    
        this.build_time[6] = new Array(); //Iron Mine
        this.build_time[6][1] = 15;
        this.build_time[6][2] = 54;
        this.build_time[6][3] = 360;
        this.build_time[6][4] = 2700;
        this.build_time[6][5] = 6075;
        this.build_time[6][6] = 12150;
        this.build_time[6][7] = 22500;
        this.build_time[6][8] = 35820;
        this.build_time[6][9] = 53880;
        this.build_time[6][10] = 81720;
    
        this.build_time[14] = new Array(); //Barracks
        this.build_time[14][1] = 15;
        this.build_time[14][2] = 36;
        this.build_time[14][3] = 240;
        this.build_time[14][4] = 1800;
        this.build_time[14][5] = 4050;
        this.build_time[14][6] = 8100;
        this.build_time[14][7] = 14760;
        this.build_time[14][8] = 23850;
        this.build_time[14][9] = 35910;
        this.build_time[14][10] = 54450;
    
        this.build_time[16] = new Array(); //Training Ground
        this.build_time[16][1] = 20;
        this.build_time[16][2] = 108;
        this.build_time[16][3] = 720;
        this.build_time[16][4] = 5400;
        this.build_time[16][5] = 12150;
        this.build_time[16][6] = 24300;
        this.build_time[16][7] = 44280;
        this.build_time[16][8] = 71550;
        this.build_time[16][9] = 107730;
        this.build_time[16][10] = 163350;
    
        this.build_time[13] = new Array(); //Townhouse
        this.build_time[13][1] = 17;
        this.build_time[13][2] = 77;
        this.build_time[13][3] = 480;
        this.build_time[13][4] = 3600;
        this.build_time[13][5] = 8100;
        this.build_time[13][6] = 16200;
        this.build_time[13][7] = 29520;
        this.build_time[13][8] = 47700;
        this.build_time[13][9] = 71820;
        this.build_time[13][10] = 108900;
    
        this.build_time[5] = new Array(); //Marketplace
        this.build_time[5][1] = 20;
        this.build_time[5][2] = 108;
        this.build_time[5][3] = 720;
        this.build_time[5][4] = 5400;
        this.build_time[5][5] = 12150;
        this.build_time[5][6] = 24300;
        this.build_time[5][7] = 44280;
        this.build_time[5][8] = 71550;
        this.build_time[5][9] = 107730;
        this.build_time[5][10] = 163350;
    
        this.build_time[43] = new Array(); //Pitfall Trap
        this.build_time[43][1] = 25;
        this.build_time[43][2] = 300;
        this.build_time[43][3] = 810;
        this.build_time[43][4] = 1500;
        this.build_time[43][5] = 2400;
        this.build_time[43][6] = 3600;
        this.build_time[43][7] = 4920;
        this.build_time[43][8] = 6600;
        this.build_time[43][9] = 8700;
        this.build_time[43][10] = 12000;
    
        this.build_time[7] = new Array(); //Sawmill
        this.build_time[7][1] = 20;
        this.build_time[7][2] = 108;
        this.build_time[7][3] = 720;
        this.build_time[7][4] = 5400;
        this.build_time[7][5] = 12150;
        this.build_time[7][6] = 24300;
        this.build_time[7][7] = 44280;
        this.build_time[7][8] = 71550;
        this.build_time[7][9] = 107730;
        this.build_time[7][10] = 163350;
    
        this.build_time[17] = new Array(); //Stable
        this.build_time[17][1] = 22;
        this.build_time[17][2] = 144;
        this.build_time[17][3] = 960;
        this.build_time[17][4] = 7200;
        this.build_time[17][5] = 16200;
        this.build_time[17][6] = 32400;
        this.build_time[17][7] = 59040;
        this.build_time[17][8] = 95400;
        this.build_time[17][9] = 143640;
        this.build_time[17][10] = 217800;
    
        this.build_time[40] = new Array(); //Guardian Tower
        this.build_time[40][1] = 25;
        this.build_time[40][2] = 300;
        this.build_time[40][3] = 810;
        this.build_time[40][4] = 1500;
        this.build_time[40][5] = 2400;
        this.build_time[40][6] = 3600;
        this.build_time[40][7] = 4920;
        this.build_time[40][8] = 6600;
        this.build_time[40][9] = 8700;
        this.build_time[40][10] = 12000;
    
        this.build_time[10] = new Array(); //Stonemason
        this.build_time[10][1] = 20;
        this.build_time[10][2] = 108;
        this.build_time[10][3] = 720;
        this.build_time[10][4] = 5400;
        this.build_time[10][5] = 12150;
        this.build_time[10][6] = 24300;
        this.build_time[10][7] = 44280;
        this.build_time[10][8] = 71550;
        this.build_time[10][9] = 107730;
        this.build_time[10][10] = 163350;
    
        this.build_time[36] = new Array(); //Moonglow Tower
        this.build_time[36][1] = 22;
        this.build_time[36][2] = 144;
        this.build_time[36][3] = 960;
        this.build_time[36][4] = 7200;
        this.build_time[36][5] = 16200;
        this.build_time[36][6] = 32400;
        this.build_time[36][7] = 59040;
        this.build_time[36][8] = 95400;
        this.build_time[36][9] = 143640;
        this.build_time[36][10] = 217800;
    
        this.build_time[44] = new Array(); //Barricade
        this.build_time[44][1] = 25;
        this.build_time[44][2] = 300;
        this.build_time[44][3] = 810;
        this.build_time[44][4] = 1500;
        this.build_time[44][5] = 2400;
        this.build_time[44][6] = 3600;
        this.build_time[44][7] = 4920;
        this.build_time[44][8] = 6600;
        this.build_time[44][9] = 8700;
        this.build_time[44][10] = 12000;
    
        this.build_time[8] = new Array(); //Mill
        this.build_time[8][1] = 20;
        this.build_time[8][2] = 108;
        this.build_time[8][3] = 720;
        this.build_time[8][4] = 5400;
        this.build_time[8][5] = 12150;
        this.build_time[8][6] = 24300;
        this.build_time[8][7] = 44280;
        this.build_time[8][8] = 71550;
        this.build_time[8][9] = 107730;
        this.build_time[8][10] = 163350;
    
        this.build_time[21] = new Array(); //Castle
        this.build_time[21][1] = 72000;
        this.build_time[21][2] = 84000;
        this.build_time[21][3] = 96000;
        this.build_time[21][4] = 108000;
        this.build_time[21][5] = 120000;
        this.build_time[21][6] = 132000;
        this.build_time[21][7] = 144000;
        this.build_time[21][8] = 156000;
        this.build_time[21][9] = 168000;
        this.build_time[21][10] = 180000;
    
        this.build_time[37] = new Array(); //Trinsic Temple
        this.build_time[37][1] = 22;
        this.build_time[37][2] = 144;
        this.build_time[37][3] = 960;
        this.build_time[37][4] = 7200;
        this.build_time[37][5] = 16200;
        this.build_time[37][6] = 32400;
        this.build_time[37][7] = 59040;
        this.build_time[37][8] = 95400;
        this.build_time[37][9] = 143640;
        this.build_time[37][10] = 217800;
    
        this.build_time[42] = new Array(); //Templar Tower
        this.build_time[42][1] = 25;
        this.build_time[42][2] = 300;
        this.build_time[42][3] = 810;
        this.build_time[42][4] = 1500;
        this.build_time[42][5] = 2400;
        this.build_time[42][6] = 3600;
        this.build_time[42][7] = 4920;
        this.build_time[42][8] = 6600;
        this.build_time[42][9] = 8700;
        this.build_time[42][10] = 12000;
    
        this.build_time[45] = new Array(); //Arcane Trap
        this.build_time[45][1] = 25;
        this.build_time[45][2] = 300;
        this.build_time[45][3] = 810;
        this.build_time[45][4] = 1500;
        this.build_time[45][5] = 2400;
        this.build_time[45][6] = 3600;
        this.build_time[45][7] = 4920;
        this.build_time[45][8] = 6600;
        this.build_time[45][9] = 8700;
        this.build_time[45][10] = 12000;
    
        this.build_time[11] = new Array(); //Foundry
        this.build_time[11][1] = 20;
        this.build_time[11][2] = 108;
        this.build_time[11][3] = 720;
        this.build_time[11][4] = 5400;
        this.build_time[11][5] = 12150;
        this.build_time[11][6] = 24300;
        this.build_time[11][7] = 44280;
        this.build_time[11][8] = 71550;
        this.build_time[11][9] = 107730;
        this.build_time[11][10] = 163350;
    
        this.build_time[39] = new Array(); //Ballista Tower
        this.build_time[39][1] = 25;
        this.build_time[39][2] = 300;
        this.build_time[39][3] = 810;
        this.build_time[39][4] = 1500;
        this.build_time[39][5] = 2400;
        this.build_time[39][6] = 3600;
        this.build_time[39][7] = 4920;
        this.build_time[39][8] = 6600;
        this.build_time[39][9] = 8700;
        this.build_time[39][10] = 12000;
    
        this.build_time[18] = new Array(); //Workshop
        this.build_time[18][1] = 25;
        this.build_time[18][2] = 180;
        this.build_time[18][3] = 1200;
        this.build_time[18][4] = 9000;
        this.build_time[18][5] = 20250;
        this.build_time[18][6] = 40500;
        this.build_time[18][7] = 73800;
        this.build_time[18][8] = 119250;
        this.build_time[18][9] = 179550;
        this.build_time[18][10] = 272250;
    
        this.build_time[22] = new Array(); //Harbor
        this.build_time[22][1] = 22;
        this.build_time[22][2] = 144;
        this.build_time[22][3] = 960;
        this.build_time[22][4] = 7200;
        this.build_time[22][5] = 16200;
        this.build_time[22][6] = 32400;
        this.build_time[22][7] = 59040;
        this.build_time[22][8] = 95400;
        this.build_time[22][9] = 143640;
        this.build_time[22][10] = 217800;
    
        this.build_time[19] = new Array(); //Shipyard
        this.build_time[19][1] = 27;
        this.build_time[19][2] = 216;
        this.build_time[19][3] = 1440;
        this.build_time[19][4] = 10800;
        this.build_time[19][5] = 24300;
        this.build_time[19][6] = 48600;
        this.build_time[19][7] = 88560;
        this.build_time[19][8] = 143100;
        this.build_time[19][9] = 215460;
        this.build_time[19][10] = 326700;
    
        this.build_time[46] = new Array(); //Camouflage Trap
        this.build_time[46][1] = 25;
        this.build_time[46][2] = 300;
        this.build_time[46][3] = 810;
        this.build_time[46][4] = 1500;
        this.build_time[46][5] = 2400;
        this.build_time[46][6] = 3600;
        this.build_time[46][7] = 4920;
        this.build_time[46][8] = 6600;
        this.build_time[46][9] = 8700;
        this.build_time[46][10] = 12000;
    
    }
    
    // ---------------------
    
    LouProof.prototype.get_lowest_level_building = function( btype) {
    	var buildings = a.visMain.getBuildings();
    	
    	var lowest_level = 10;
    	var lowest_bld;
        var lowest_time = 10000000;
    	var s='';
    	
    	for (var i in buildings) {
    		
    		if( isNaN(i)) continue;
    		
    		bld = buildings[i];
    
    		var el = bld.getLevel() + this.qcount( bld); // effective level (level + queue entry count)
    		
            if( (el < lowest_level && localStorage["lowest_build_time"] != "true") ||
                ( localStorage["lowest_build_time"] == "true"
                    && this.build_time[ bld.getType()][ el+1] < lowest_time)
            ) {
    
                if( this.is_resource( bld.getType())) continue;
                if( btype == 'common'   && !this.is_common_btype( bld.getType())) continue;
                if( btype == 'tower'    && !this.is_tower( bld.getType())) continue;
                if( btype == 'barracks' && !this.is_barracks( bld.getType())) continue;
                if( btype == 'cottage'  && !this.is_cottage( bld.getType())) continue;
                if( btype == 'military' && !this.is_military( bld.getType())) continue;
    
                if( debuck && lowest_bld) { // -- Debug information
                    console.log( "switching level "+lowest_level+" "+this.getBldTypeName( lowest_bld.getType())+" ("+lowest_time+")"
                    +" with level "+bld.getLevel()+" "+ this.getBldTypeName( bld.getType())+" ("+this.build_time[ bld.getType()][ el+1]+")"
                    );
                    console.log( (el < lowest_level && localStorage["lowest_build_time"] != "true"));
                    console.log( ( localStorage["lowest_build_time"] == "true" && this.build_time[ bld.getType()][ el+1] < lowest_time));
                }
                // -- debug
    
                if( debuck) console.log( 'get_llb: bld.getLevel() = '+bld.getLevel()+
                    ', qcount( bld) = '+this.qcount(bld)+
                    ', el = '+el+
                    ', lowest_level = '+lowest_level);
                lowest_bld = bld;
                lowest_level = el;
                lowest_time = this.build_time[ bld.getType()][ el+1];
            }
    	}
    	
    	if( debuck) console.log( bld);
    
    	return( lowest_bld);
    }
    
    louproof = new LouProof();
    setTimeout( "louproof.init();", 5000);
    
}

var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ injection +')();'));
(document.body || document.head || document.documentElement).appendChild(script);

